﻿using System;
using System.Collections.Generic;

using System.Text;
using Silk.NET.Core.Native;
using TTEngine.Resource;
using TTEngine.TTMath;
using voidbox;

namespace TTEngine.Graphics
{
    public struct FrameInfo
    {
        public uint DrawCount;
        public uint DrawElemCount;
        public DateTime FrameBegin;
        public DateTime FrameEnd;
    }
    //收集一个基本的渲染信息
    public class RenderInfo
    {
        public uint DrawCount;
        public uint DrawElemCount;
        public DateTime FrameBegin;
        public int HistoryMaxCount
        {
            get;
            private set;
        }
        public float MaxDelta
        {
            get
            {
                float deltamax = 0;
                for (var i = 0; i < History.Count; i++)
                {
                    var delta = (float)(History[i].FrameEnd - History[i].FrameBegin).TotalSeconds;
                    if (deltamax < delta)
                        deltamax = delta;
                }
                return deltamax;
            }
        }
        public float Fps
        {
            get
            {
                if (History.Count > 2)
                {
                    var delta = (History.Last().FrameBegin - History.First().FrameBegin).TotalSeconds;
                    var fps = (History.Count - 1) / delta;
                    return (float)fps;
                }
                return 0;
            }
        }
        public RenderInfo(int historyCount = 120)
        {

            HistoryMaxCount = historyCount;
        }

        public RandomAccessQueue<FrameInfo> History = new RandomAccessQueue<FrameInfo>();
        public void RecordFrame_Begin()
        {
            DrawCount = 0;
            DrawElemCount = 0;
            FrameBegin = DateTime.Now;
        }
        public void RecordFrame_End()
        {
            History.Enqueue(new FrameInfo()
            {
                DrawCount = this.DrawCount,
                DrawElemCount = this.DrawElemCount,
                FrameBegin = this.FrameBegin,
                FrameEnd = DateTime.Now
            });
            if (History.Count > HistoryMaxCount)
                History.Dequeue();
        }
        public void DrawStats(CommonResource _resource, PackedTextureBatcher render, fAABB rect, float scale, bool withBorder = false)
        {
            render.EndDraw();
            render.ZTest = false;
            render.ZWrite = false;

            //if (withBorder)
            //{
            //    render.DrawSpriteScale9(_resource.PackedTextureGroup, _resource.BlockBorderRound,
            //  Border.Create(3), scale,
            // rect, 0, Color.White);
            //}
            var maxtime = MaxDelta;
            if (History.Count > 2)
            {
                var fps = Fps;

                if (withBorder)
                {
                    for (var x = 0; x < History.Count; x++)
                    {
                        var index = History.Count - 1 - x;

                        float linex2 = rect.x2 - (4 + x * 2) * scale;
                        float liney2 = rect.y2 - 4 * scale;
                        float h = (float)(History[index].FrameEnd - History[index].FrameBegin).TotalMilliseconds / maxtime;
                        if (h > 1.0f) h = 1.0f;
                        float liney1 = liney2 - 32 * h * scale;
                        render.DrawSprite(_resource.PackedTextureGroup, _resource.BlockWhite,
                      new fAABB(linex2 - (1) * scale + 1 * scale, liney1 + 1 * scale, linex2 + 1 * scale, liney2 + 1 * scale), 0,
                      new Color(0f, 0f, 0f, 0.5f));

                        render.DrawSprite(_resource.PackedTextureGroup, _resource.BlockWhite,
                            new fAABB(linex2 - (1) * scale, liney1, linex2, liney2), 0,
                            new Color(0.1f, 0.4f, 0.8f, 0.8f));

                    }
                }
                render.DrawFont(_resource.AscII12, "Fps:" + fps.ToString("f02"), rect.x1 + 5 * scale, rect.y1 + 5 * scale, 0, new Color(0, 0, 0, 0.5f), scale, 1);
                render.DrawFont(_resource.AscII12, "MaxDrawTime(MS):" + maxtime.ToString("f02"), rect.x1 + 5 * scale, rect.y1 + 17 * scale, 0, new Color(0, 0, 0, 0.5f), scale, 1);
                render.DrawFont(_resource.AscII12, "DrawCall:" + this.DrawCount, rect.x1 + 5 * scale, rect.y1 + 29 * scale, 0, new Color(0, 0, 0, 0.5f), scale, 1);
                render.DrawFont(_resource.AscII12, "DrawElem:" + this.DrawElemCount, rect.x1 + 5 * scale, rect.y1 + 41 * scale, 0, new Color(0, 0, 0, 0.5f), scale, 1);
                render.DrawFont(_resource.AscII12, "Fps:" + fps.ToString("f02"), rect.x1 + 4 * scale, rect.y1 + 4 * scale, 0, Color.White, scale, 1);
                render.DrawFont(_resource.AscII12, "MaxDrawTime(MS):" + maxtime.ToString("f02"), rect.x1 + 4 * scale, rect.y1 + 16 * scale, 0, Color.White, scale, 1);
                render.DrawFont(_resource.AscII12, "DrawCall:" + this.DrawCount, rect.x1 + 4 * scale, rect.y1 + 28 * scale, 0, Color.White, scale, 1);
                render.DrawFont(_resource.AscII12, "DrawElem:" + this.DrawElemCount, rect.x1 + 4 * scale, rect.y1 + 40 * scale, 0, Color.White, scale, 1);

            }
            render.EndDraw();
        }
    }
}
